home *** CD-ROM | disk | FTP | other *** search
- /* ------------------- decomp.c -------------------- */
-
- /*
- * Decompress the application.HLP file
- * or load the application.TXT file if the .HLP file
- * does not exist
- */
-
- #include <assert.h>
- #include "dflat.h"
- #include "htree.h"
-
- static int in8;
- static int ct8 = 8;
- static FILE *fi;
- static BYTECOUNTER bytectr;
- struct htr *HelpTree;
- static int root;
-
- /* ------- open the help database file -------- */
- FILE *OpenHelpFile(const char *fn, const char *md)
- {
- char *cp;
- int treect, i;
- char helpname[65];
-
- /* -------- get the name of the help file ---------- */
- BuildFileName(helpname, fn, ".hlp");
- if ((fi = fopen(helpname, md)) == NULL)
- return NULL;
- if (HelpTree == NULL) {
- /* ----- read the byte count ------ */
- fread(&bytectr, sizeof bytectr, 1, fi);
- /* ----- read the frequency count ------ */
- fread(&treect, sizeof treect, 1, fi);
- /* ----- read the root offset ------ */
- fread(&root, sizeof root, 1, fi);
- HelpTree = calloc(treect-256, sizeof(struct htr));
- if (HelpTree != NULL) {
- /* ---- read in the tree --- */
- for (i = 0; i < treect-256; i++) {
- fread(&HelpTree[i].left, sizeof(int), 1, fi);
- fread(&HelpTree[i].right, sizeof(int), 1, fi);
- }
- }
- }
- return fi;
- }
-
- /* ----- read a line of text from the help database ----- */
- void *GetHelpLine(char *line)
- {
- int h;
- *line = '\0';
- while (TRUE) {
- /* ----- decompress a line from the file ------ */
- h = root;
- /* ----- walk the Huffman tree ----- */
- while (h > 255) {
- /* --- h is a node pointer --- */
- if (ct8 == 8) {
- /* --- read 8 bits of compressed data --- */
- if ((in8 = fgetc(fi)) == EOF) {
- *line = '\0';
- return NULL;
- }
- ct8 = 0;
- }
- /* -- point to left or right node based on msb -- */
- if (in8 & 0x80)
- h = HelpTree[h-256].left;
- else
- h = HelpTree[h-256].right;
- /* --- shift the next bit in --- */
- in8 <<= 1;
- ct8++;
- }
- /* --- h < 255 = decompressed character --- */
- if (h == '\r')
- continue; /* skip the '\r' character */
- /* --- put the character in the buffer --- */
- *line++ = h;
- /* --- if '\n', end of line --- */
- if (h == '\n')
- break;
- }
- *line = '\0'; /* null-terminate the line */
- return line;
- }
-
- /* --- compute the database file byte and bit position --- */
- void HelpFilePosition(long *offset, int *bit)
- {
- *offset = ftell(fi);
- if (ct8 < 8)
- --*offset;
- *bit = ct8;
- }
-
- /* -- position the database to the specified byte and bit -- */
- void SeekHelpLine(long offset, int bit)
- {
- int fs = fseek(fi, offset, 0);
- assert(fs == 0);
- ct8 = bit;
- if (ct8 < 8) {
- in8 = fgetc(fi);
- in8 <<= bit;
- }
- }
-
-